<?php
/**
 * User: madis
 * Date: 26.09.2009
 * Time: 18:20:56
 */

class VEvent {

    private $info;
    private $week;
    private $outcomeCache = '';
    private $numberOfWeekday;
    private $lastWeek = 0;
    private $beginTime;
    private $endTime;
    private $year = ACADEMIC_YEAR;

    // Monday to Sunday (0, 1, 2..., 7)
    private $weekDayAbbreviations = array('', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU');

    public function __construct($info, $week, $numberOfWeekday, $lastWeek = 0) {

        $this->info = $info;
        $this->week = $week;
        $this->numberOfWeekday = $numberOfWeekday;
        $this->lastWeek = $lastWeek;

        $this->addICSEventHeader();
        $this->addICSURL();
        $this->addICSBeginDateOfFirstLesson();
        $this->addICSEndDateOfFirstLesson();
        if ($this->lastWeek) { // When the date is a period
            $this->addICSPeriodInformation();
        }
        $this->addICSDescription();
        $this->addICSSummary();
        $this->addICSLocation();
        $this->addICSEventFooter();
    }

    public function getContent() {
        return $this->outcomeCache;
    }

    private function addICSEventHeader() {
        $this->outcomeCache .= "BEGIN:VEVENT\n";
    }
    private function addICSURL() {
        $this->outcomeCache .= 'URL:https://www.is.ut.ee/pls/ois/'."\n";
    }
    private function addICSBeginDateOfFirstLesson() {
        $this->beginTime = $this->info['ALGUSKELL'];
        $beginDateOfFirstLesson = $this->makeDate($this->beginTime, $this->week);

        $this->outcomeCache .= 'DTSTART;TZID=Europe/Tallinn:'.$beginDateOfFirstLesson."\n";
    }
    private function addICSEndDateOfFirstLesson() {
        $this->endTime = $this->info['LOPPKELL'];
        $endDateOfFirstLesson = $this->makeDate($this->endTime, $this->week);

        $this->outcomeCache .= 'DTEND;TZID=Europe/Tallinn:'.$endDateOfFirstLesson."\n";
    }
    private function addICSPeriodInformation() {
        $weekDayAbbreviation = $this->weekDayAbbreviations[$this->numberOfWeekday];
        $lastOccurrenceDate = $this->makeDate($this->endTime, $this->lastWeek);

        $this->outcomeCache .= 'RRULE:FREQ=WEEKLY;WKST=SU;UNTIL='.$lastOccurrenceDate.';BYDAY='.$weekDayAbbreviation."\n";
    }
    private function addICSDescription() {
        $group = $this->addSlashesAndImplodeIfArray($this->info['CP_RYHM']);
        $lecturer = $this->addSlashesAndImplodeIfArray($this->info['CF_OPPEJOUD']);
        $code = addslashes($this->info['CP_AINE_KOOD']);

        $this->outcomeCache .= 'DESCRIPTION:'.$group.' '.$lecturer.' '.$code."\n";
    }
    private function addICSSummary() {
        $name = addslashes($this->info['CP_AINE_NIMETUS']);
        $location = is_string($this->info['CP_KOHT'])? addslashes($this->info['CP_KOHT']) : '';
        $this->outcomeCache .= 'SUMMARY:'.$name.' '.$location."\n";
    }
    private function addICSLocation() {
        $location = is_string($this->info['CP_KOHT'])? addslashes($this->info['CP_KOHT']) : '';
        $this->outcomeCache .= 'LOCATION:'.$location."\n";
    }
    private function addICSEventFooter() {
        $this->outcomeCache .= "END:VEVENT\n";
    }

    private function addSlashesAndImplodeIfArray($input) {
        return addslashes($this->implodeIfArray($input));
    }

    private function implodeIfArray($input) {
        if (is_array($input)) {
            $input = implode(', ', $input);
        }
        return $input;
    }

    private function makeDate($time, $numberOfWeek) {

        $time = $this->formattedTime($time);

        $date = $this->dateFromNumberOfWeekday($this->year, $numberOfWeek);
        $monthDayAndMonth = date("md", $date);
        $dateAndTime = $this->year.$monthDayAndMonth.'T'.$time;

        return $dateAndTime;
    }

    private function formattedTime($time) {
    // Remove all points if there are any
        $time = str_replace('.', '', $time);
        $offset = 0;

        // Have leading 0, if time is i.e 800 or 9
        if (strlen($time)%2 != 0) {
            $offset = 1;
        }

        $wantedTimeFormat = '000000';
        $time = substr_replace($wantedTimeFormat, $time, $offset, strlen($time));

        return $time;
    }

    private function dateFromNumberOfWeekday($year, $numberOfWeek) {
        $numberOfWeekday = $this->numberOfWeekday;
        $numberOfWeekdayFromFourthJanuary = date("w", mktime (0,0,0,1,4,$year)); //always first week
        if ($numberOfWeekdayFromFourthJanuary==0) $numberOfWeekdayFromFourthJanuary=7;

        $dateFromNumberOfWeekday=mktime(0,0,0,1,4,$year)+((($numberOfWeek-1)*7+($numberOfWeekday-$numberOfWeekdayFromFourthJanuary))*86400);
        return $dateFromNumberOfWeekday;
    }

}